<template>
  <button
    :class="{
      'is-liked': isLiked,
      'is-loading': loading,
      'show-animation': showAnimation,
      [`size-${size}`]: true,
      [`variant-${variant}`]: true
    }"
    :disabled="disabled || loading"
    class="like-button"
    @click="handleLike"
  >
    <!-- 点赞图标 -->
    <div class="like-icon">
      <svg v-if="loading" class="loading-spinner" fill="none" viewBox="0 0 24 24">
        <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
        <path d="M12 6v6l4 2" stroke="currentColor" stroke-width="2"/>
      </svg>

      <svg v-else-if="iconType === 'heart'" class="heart-icon" fill="none" viewBox="0 0 24 24">
        <path
          :fill="isLiked ? 'currentColor' : 'none'"
          d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"
          stroke="currentColor"
          stroke-width="2"
        />
      </svg>

      <svg v-else-if="iconType === 'thumb'" class="thumb-icon" fill="none" viewBox="0 0 24 24">
        <path
          :fill="isLiked ? 'currentColor' : 'none'"
          d="M7 10v12M15 5l-1.5 6.5H21a2 2 0 0 1 2 2v.5a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V10a2 2 0 0 1 2-2h5.5L15 5z"
          stroke="currentColor"
          stroke-width="2"
        />
      </svg>

      <svg v-else class="star-icon" fill="none" viewBox="0 0 24 24">
        <path
          :fill="isLiked ? 'currentColor' : 'none'"
          d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"
          stroke="currentColor"
          stroke-width="2"
        />
      </svg>

      <!-- 点赞动画效果 -->
      <div v-if="showAnimation" class="like-animation">
        <div v-for="i in 6" :key="i" :style="{ '--delay': i * 0.1 + 's' }" class="animation-heart">
          {{ animationIcon }}
        </div>
      </div>
    </div>

    <!-- 点赞数量 -->
    <span v-if="showCount" :class="{ 'count-updating': countUpdating }" class="like-count">
      {{ displayCount }}
    </span>

    <!-- 点赞文本 -->
    <span v-if="showText" class="like-text">
      {{ likeText }}
    </span>

    <!-- 涟漪效果 -->
    <div v-if="showRipple" :style="rippleStyle" class="ripple-effect"></div>
  </button>
</template>

<script lang="ts" setup>
import { ref, computed, watch, nextTick } from 'vue'

// Props
interface Props {
  modelValue?: boolean
  count?: number
  iconType?: 'heart' | 'thumb' | 'star'
  size?: 'small' | 'medium' | 'large'
  variant?: 'default' | 'filled' | 'outline' | 'text'
  disabled?: boolean
  showCount?: boolean
  showText?: boolean
  showAnimation?: boolean
  animationDuration?: number
  debounceTime?: number
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: false,
  count: 0,
  iconType: 'heart',
  size: 'medium',
  variant: 'default',
  disabled: false,
  showCount: true,
  showText: false,
  showAnimation: true,
  animationDuration: 1000,
  debounceTime: 300
})

// Emits
const emit = defineEmits<{
  'update:modelValue': [value: boolean]
  'like': [isLiked: boolean, count: number]
  'click': [event: MouseEvent]
}>()

// 响应式数据
const isLiked = ref(props.modelValue)
const currentCount = ref(props.count)
const loading = ref(false)
const showAnimation = ref(false)
const countUpdating = ref(false)
const showRipple = ref(false)
const rippleStyle = ref({})

// 防抖控制
const debounceTimer = ref<NodeJS.Timeout>()

// 计算属性
const displayCount = computed(() => {
  if (currentCount.value === 0) return ''
  if (currentCount.value < 1000) return currentCount.value.toString()
  if (currentCount.value < 10000) return (currentCount.value / 1000).toFixed(1) + 'k'
  return (currentCount.value / 10000).toFixed(1) + 'w'
})

const likeText = computed(() => {
  if (props.iconType === 'heart') {
    return isLiked.value ? '已喜欢' : '喜欢'
  } else if (props.iconType === 'thumb') {
    return isLiked.value ? '已点赞' : '点赞'
  } else {
    return isLiked.value ? '已收藏' : '收藏'
  }
})

const animationIcon = computed(() => {
  switch (props.iconType) {
    case 'heart': return '❤️'
    case 'thumb': return '👍'
    case 'star': return '⭐'
    default: return '❤️'
  }
})

// 监听器
watch(() => props.modelValue, (newValue) => {
  isLiked.value = newValue
})

watch(() => props.count, (newValue) => {
  if (newValue !== currentCount.value) {
    animateCountChange(newValue)
  }
})

// 方法
const handleLike = async (event: MouseEvent) => {
  if (props.disabled || loading.value) return

  emit('click', event)

  // 防抖处理
  if (debounceTimer.value) {
    clearTimeout(debounceTimer.value)
  }

  debounceTimer.value = setTimeout(async () => {
    await performLike(event)
  }, props.debounceTime)
}

const performLike = async (event: MouseEvent) => {
  try {
    loading.value = true

    const newLikedState = !isLiked.value
    const newCount = currentCount.value + (newLikedState ? 1 : -1)

    // 立即更新UI状态（乐观更新）
    isLiked.value = newLikedState
    animateCountChange(newCount)

    // 显示动画效果
    if (props.showAnimation && newLikedState) {
      triggerAnimation()
    }

    // 显示涟漪效果
    triggerRipple(event)

    // 触发事件
    emit('update:modelValue', newLikedState)
    emit('like', newLikedState, newCount)

    // 模拟API调用延迟
    await new Promise(resolve => setTimeout(resolve, 200))

  } catch (error) {
    // 发生错误时回滚状态
    console.error('Like operation failed:', error)
    isLiked.value = !isLiked.value
    animateCountChange(currentCount.value + (isLiked.value ? 1 : -1))
  } finally {
    loading.value = false
  }
}

const animateCountChange = (newCount: number) => {
  if (!props.showCount) return

  countUpdating.value = true

  nextTick(() => {
    currentCount.value = newCount

    setTimeout(() => {
      countUpdating.value = false
    }, 300)
  })
}

const triggerAnimation = () => {
  showAnimation.value = true

  setTimeout(() => {
    showAnimation.value = false
  }, props.animationDuration)
}

const triggerRipple = (event: MouseEvent) => {
  const button = event.currentTarget as HTMLButtonElement
  const rect = button.getBoundingClientRect()
  const size = Math.max(rect.width, rect.height)
  const x = event.clientX - rect.left - size / 2
  const y = event.clientY - rect.top - size / 2

  rippleStyle.value = {
    width: size + 'px',
    height: size + 'px',
    left: x + 'px',
    top: y + 'px'
  }

  showRipple.value = true

  setTimeout(() => {
    showRipple.value = false
  }, 600)
}

// 暴露给父组件的方法
defineExpose({
  triggerLike: () => {
    const fakeEvent = new MouseEvent('click')
    handleLike(fakeEvent)
  },
  setLiked: (liked: boolean) => {
    isLiked.value = liked
    emit('update:modelValue', liked)
  },
  setCount: (count: number) => {
    animateCountChange(count)
  }
})
</script>

<style lang="scss" scoped>
.like-button {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  border: none;
  background: none;
  cursor: pointer;
  border-radius: 8px;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;

  &:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  // 尺寸变体
  &.size-small {
    padding: 0.375rem 0.75rem;
    font-size: 0.75rem;

    .like-icon {
      svg {
        width: 14px;
        height: 14px;
      }
    }
  }

  &.size-medium {
    padding: 0.5rem 1rem;
    font-size: 0.875rem;

    .like-icon {
      svg {
        width: 16px;
        height: 16px;
      }
    }
  }

  &.size-large {
    padding: 0.75rem 1.5rem;
    font-size: 1rem;

    .like-icon {
      svg {
        width: 20px;
        height: 20px;
      }
    }
  }

  // 样式变体
  &.variant-default {
    color: #6b7280;

    &:hover {
      color: #374151;
      background: rgba(0, 0, 0, 0.05);
    }

    &.is-liked {
      color: #ef4444;

      &:hover {
        color: #dc2626;
      }
    }
  }

  &.variant-filled {
    background: #f3f4f6;
    color: #6b7280;

    &:hover {
      background: #e5e7eb;
      color: #374151;
    }

    &.is-liked {
      background: #fef2f2;
      color: #ef4444;

      &:hover {
        background: #fecaca;
        color: #dc2626;
      }
    }
  }

  &.variant-outline {
    border: 1px solid #e5e7eb;
    color: #6b7280;

    &:hover {
      border-color: #d1d5db;
      background: rgba(0, 0, 0, 0.05);
    }

    &.is-liked {
      border-color: #ef4444;
      color: #ef4444;
      background: #fef2f2;

      &:hover {
        border-color: #dc2626;
        background: #fecaca;
      }
    }
  }

  &.variant-text {
    padding: 0.25rem 0.5rem;

    &:hover {
      background: rgba(0, 0, 0, 0.05);
    }
  }

  .like-icon {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;

    svg {
      transition: all 0.2s ease;

      &.loading-spinner {
        animation: spin 1s linear infinite;
      }
    }

    .like-animation {
      position: absolute;
      inset: 0;
      pointer-events: none;

      .animation-heart {
        position: absolute;
        font-size: 12px;
        animation: heartFloat 1s ease-out forwards;
        animation-delay: var(--delay);

        &:nth-child(1) { transform: rotate(-30deg); }
        &:nth-child(2) { transform: rotate(-15deg); }
        &:nth-child(3) { transform: rotate(0deg); }
        &:nth-child(4) { transform: rotate(15deg); }
        &:nth-child(5) { transform: rotate(30deg); }
        &:nth-child(6) { transform: rotate(45deg); }
      }
    }
  }

  .like-count {
    font-weight: 500;
    transition: all 0.3s ease;

    &.count-updating {
      transform: scale(1.1);
      color: #ef4444;
    }
  }

  .like-text {
    font-weight: 500;
  }

  .ripple-effect {
    position: absolute;
    border-radius: 50%;
    background: rgba(239, 68, 68, 0.3);
    transform: scale(0);
    animation: ripple 0.6s linear;
    pointer-events: none;
  }

  // 点击时的缩放效果
  &.is-loading {
    transform: scale(0.95);
  }

  // 点赞状态的弹跳动画
  &.show-animation.is-liked {
    animation: likeButton 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);

    .like-icon svg {
      animation: likeIcon 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
    }
  }
}

// 动画定义
@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@keyframes heartFloat {
  0% {
    transform: translateY(0) scale(0);
    opacity: 1;
  }
  50% {
    opacity: 1;
  }
  100% {
    transform: translateY(-20px) scale(1);
    opacity: 0;
  }
}

@keyframes ripple {
  to {
    transform: scale(4);
    opacity: 0;
  }
}

@keyframes likeButton {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.1); }
}

@keyframes likeIcon {
  0% { transform: scale(1); }
  50% { transform: scale(1.2); }
  100% { transform: scale(1); }
}

// 响应式适配
@media (max-width: 768px) {
  .like-button {
    &.size-small {
      padding: 0.25rem 0.5rem;
      font-size: 0.7rem;

      .like-icon svg {
        width: 12px;
        height: 12px;
      }
    }

    &.size-medium {
      padding: 0.375rem 0.75rem;
      font-size: 0.8rem;

      .like-icon svg {
        width: 14px;
        height: 14px;
      }
    }

    &.size-large {
      padding: 0.5rem 1rem;
      font-size: 0.875rem;

      .like-icon svg {
        width: 18px;
        height: 18px;
      }
    }

    // 移动端触摸优化
    min-height: 44px;
    min-width: 44px;
  }
}

// 暗色模式支持
@media (prefers-color-scheme: dark) {
  .like-button {
    &.variant-default {
      color: #9ca3af;

      &:hover {
        color: #d1d5db;
        background: rgba(255, 255, 255, 0.1);
      }
    }

    &.variant-filled {
      background: #374151;
      color: #9ca3af;

      &:hover {
        background: #4b5563;
        color: #d1d5db;
      }

      &.is-liked {
        background: #7f1d1d;
        color: #fca5a5;

        &:hover {
          background: #991b1b;
          color: #f87171;
        }
      }
    }

    &.variant-outline {
      border-color: #4b5563;
      color: #9ca3af;

      &:hover {
        border-color: #6b7280;
        background: rgba(255, 255, 255, 0.1);
      }
    }
  }
}

// 高对比度模式支持
@media (prefers-contrast: high) {
  .like-button {
    border: 1px solid currentColor;

    &.variant-filled {
      border: 2px solid currentColor;
    }
  }
}

// 减少动画偏好支持
@media (prefers-reduced-motion: reduce) {
  .like-button {
    transition: none;

    * {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
    }
  }
}
</style>
